package com.yxinsur.imc.business.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yxinsur.imc.business.domain.*;
import com.yxinsur.imc.business.enums.ExpenseExpressionMsgTypeEnum;
import com.yxinsur.imc.business.enums.FundMonthlyStrategyEnum;
import com.yxinsur.imc.business.enums.IsDeletedEnum;
import com.yxinsur.imc.business.fact.BasicFACT;
import com.yxinsur.imc.business.form.CommForm;
import com.yxinsur.imc.business.form.ExamCommForm;
import com.yxinsur.imc.business.mapper.*;
import com.yxinsur.imc.business.service.BasicService;
import com.yxinsur.imc.business.service.IImcCommService;
import com.yxinsur.imc.business.service.IImcRecnExpenseService;
import com.yxinsur.imc.business.vo.BrokerVo;
import com.yxinsur.imc.business.vo.CommDetailsVo;
import com.yxinsur.imc.business.vo.CommVo;
import com.yxinsur.imc.business.vo.OrderRiskToCommRiskVo;
import com.yxinsur.imc.common.exception.BaseException;
import com.yxinsur.imc.common.exception.BusinessException;
import com.yxinsur.imc.common.utils.DateUtils;
import com.yxinsur.imc.common.utils.SecurityUtils;
import com.yxinsur.imc.common.utils.StringUtils;
import com.yxinsur.imc.system.mapper.SysOrgMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 佣金报主Service业务层处理
 *
 * @author imc
 * @date 2021-05-25
 */
@Service
public class ImcCommServiceImpl extends ServiceImpl<ImcCommMapper, ImcComm> implements IImcCommService {
    @Autowired
    private ImcCommMapper imcCommMapper;
    @Autowired
    private ImcTeamMapper imcTeamMapper;
    @Autowired
    private ImcBrokerMapper imcBrokerMapper;
    @Autowired
    private ImcCommDetailsMapper imcCommDetailsMapper;
    @Autowired
    private ImcOrderRiskMapper imcOrderRiskMapper;
    @Autowired
    private ImcFundMapper imcFundMapper;
    @Autowired
    private ImcCommRiskMapper imcCommRiskMapper;
    @Autowired
    private SysOrgMapper sysOrgMapper;
    @Autowired
    private BasicService basicService;

    @Autowired
    private ImcFundOrderExpressionMapper fundOrderExpressionMapper;

    @Autowired
    private ImcFundOrderVariableMapper fundOrderVariableMapper;
    @Autowired
    private IImcRecnExpenseService recnExpenseService;
    @Autowired
    private ImcFundBrokerExpressionMapper fundBrokerExpressionMapper;
    @Autowired
    private ImcFundBrokerVariableMapper fundBrokerVariableMapper;

    /**
     * 查询佣金报主
     *
     * @param id 佣金报主ID
     * @return 佣金报主
     */
    @Override
    public ImcComm selectImcCommById(Long id) {
        return imcCommMapper.selectImcCommById(id);
    }

    /**
     * 查询佣金报主列表
     *
     * @param imcComm 佣金报主
     * @return 佣金报主
     */
    @Override
    public List<CommVo> selectImcCommList(CommForm commForm) {
        commForm.setTenantId(SecurityUtils.getTenantId());
        String authOrgIds = SecurityUtils.getLoginUser().getAuthOrgIds();
        String[] orgIdArr = authOrgIds.split(",");
        return imcCommMapper.selectImcCommList(commForm,orgIdArr);
    }

    /**
     * 新增佣金报主
     *
     * @param imcComm 佣金报主
     * @return 结果
     */
    @Override
    public int insertImcComm(ImcComm imcComm) {
        imcComm.setCreateTime(DateUtils.getNowDate());
        return imcCommMapper.insertImcComm(imcComm);
    }

    /**
     * 修改佣金报主
     *
     * @param imcComm 佣金报主
     * @return 结果
     */
    @Override
    public int updateImcComm(ImcComm imcComm) {
        imcComm.setUpdateTime(DateUtils.getNowDate());
        return imcCommMapper.updateImcComm(imcComm);
    }

    /**
     * 批量删除佣金报主
     *
     * @param ids 需要删除的佣金报主ID
     * @return 结果
     */
    @Override
    public int deleteImcCommByIds(String[] ids) {
        return imcCommMapper.deleteImcCommByIds(ids);
    }

    /**
     * 删除佣金报主信息
     *
     * @param id 佣金报主ID
     * @return 结果
     */
    @Override
    public int deleteImcCommById(Long id) {
        //查询佣金主表信息  如果为D不能删除 只能反结操作
        ImcComm imcComm1 = imcCommMapper.selectImcCommById(id);
        if ("E".equals(imcComm1.getStatus())) {
            throw new BusinessException("状态为已完成，不能删除");
        }
        ImcComm imcComm = new ImcComm();
        imcComm.setId(id);
        imcComm.setIsDeleted(id.toString());
        return imcCommMapper.updateImcComm(imcComm);
    }


    /**
     * 险种计算2
     *
     * @param orgId
     * @param calculateDate
     */
    @Transactional
    @Override
    public void calculate(Long orgId, Date calculateDate, Long fundId) {
        Long tenantId = SecurityUtils.getTenantId();
        //先查询下主表信息 同机构 月度只能计算一次

        //保存佣金主表
        ImcComm imcComm = new ImcComm();
        String yearMonth = DateUtils.parseDateToStr(DateUtils.YYYY_MM, calculateDate);
        imcComm.setSettleMonth(yearMonth);
        imcComm.setFundId(fundId);
        imcComm.setStatus("A");
        imcComm.setOrgId(orgId);
        imcComm.setTenantId(tenantId);

        ImcComm imcCommTemp = imcCommMapper.getImcComm(imcComm);
        if (imcCommTemp != null) {
           log.debug("该机构在结算月份已存在佣金数据。");
        }

        imcCommMapper.insertImcComm(imcComm);

        //查询基本法相关信息 获得基本法结算口径
        ArrayList<ImcCommRisk> commRisks = getCommRiskList(imcComm,calculateDate,fundId);
        commRisks.removeAll(Collections.singleton(null));
        if(CollectionUtils.isEmpty(commRisks)){
            throw new BusinessException("该机构在该结算月份不存在保单数据。");
        }
        imcCommRiskMapper.insertImcCommRiskList(commRisks);
    }

    private ArrayList<ImcCommRisk> getCommRiskList(ImcComm imcComm,Date calculateDate, Long fundId) {
        Long tenantId = SecurityUtils.getTenantId();
        ArrayList<ImcCommRisk> returnCommRiskList = new ArrayList<>();
        String criteriaSQL = getCriteriaSQL(calculateDate,fundId,"A");
        if(StringUtils.isNotBlank(criteriaSQL)){
            List<OrderRiskToCommRiskVo> orderRisks = imcOrderRiskMapper.selectOrderRiskBySqlParam(criteriaSQL, tenantId);
            for (OrderRiskToCommRiskVo orderRisk : orderRisks) {
                ImcCommRisk imcCommRisk = new ImcCommRisk();
                BeanUtils.copyProperties(orderRisk, imcCommRisk);
                imcCommRisk.setCommId(imcComm.getId());
                imcCommRisk.setOrderRiskId(orderRisk.getId());
                imcCommRisk.setCreateId(SecurityUtils.getUsername());
                imcCommRisk.setCreateTime(DateUtils.getNowDate());
                imcCommRisk.setUpdateId(SecurityUtils.getUsername());
                imcCommRisk.setUpdateTime(DateUtils.getNowDate());
                imcCommRisk.setTenantId(tenantId);
                imcCommRisk.setIsDeleted(IsDeletedEnum.N.getCode());
                returnCommRiskList.add(imcCommRisk);
            }
        }

        //续期险种数据
        String criteriaRenwSQL = getCriteriaSQL(calculateDate,fundId,"B");
        if(StringUtils.isNotBlank(criteriaRenwSQL)){
            List<OrderRiskToCommRiskVo> commRiskVos = imcOrderRiskMapper.selectOrderRiskBySqlParam(criteriaRenwSQL, tenantId);
            for (OrderRiskToCommRiskVo commRiskVo : commRiskVos) {
                ImcCommRisk imcCommRisk = new ImcCommRisk();
                BeanUtils.copyProperties(commRiskVo, imcCommRisk);
                //保存续期的直接佣金
                imcCommRisk.setCommission(imcCommRisk.getPaymentPrem().multiply(imcCommRisk.getCommissionRate()));
                imcCommRisk.setCommId(imcComm.getId());
                imcCommRisk.setOrderRiskId(commRiskVo.getId());
                imcCommRisk.setCreateId(SecurityUtils.getUsername());
                imcCommRisk.setCreateTime(DateUtils.getNowDate());
                imcCommRisk.setUpdateId(SecurityUtils.getUsername());
                imcCommRisk.setUpdateTime(DateUtils.getNowDate());
                imcCommRisk.setTenantId(tenantId);
                imcCommRisk.setIsDeleted(IsDeletedEnum.N.getCode());
                returnCommRiskList.add(imcCommRisk);
            }
        }
        return returnCommRiskList;
    }

    private String getCriteriaSQL(Date calculateDate, Long fundId,String policyYearFlag) {
        StringBuilder criteriaSQL = new StringBuilder();
        List<ImcFundOrderExpression> fundOrderExpressions = this.fundOrderExpressionMapper.listfundOrderExpressionByFundId(fundId,policyYearFlag,SecurityUtils.getTenantId());
        if (CollUtil.isNotEmpty(fundOrderExpressions)) {
            for (ImcFundOrderExpression item : fundOrderExpressions) {
                // a.解析：口径字段（字段名称）：如果不为括号则转换为 ior.字段名
                ImcFundOrderVariable fundOrderVariable = this.fundOrderVariableMapper.selectImcFundOrderVariableById(item.getOrderVariableId());
                if ("left_bracket".equals(fundOrderVariable.getVariableName()) || "right_bracket".equals(fundOrderVariable.getVariableName())) {
                    criteriaSQL.append(fundOrderVariable.getVariableLabel());
                } else {
                    criteriaSQL.append("r.").append(fundOrderVariable.getVariableName());
                }

                // b.解析：运算符
                criteriaSQL.append(" ").append(recnExpenseService.transOperator(item.getOperator(), ExpenseExpressionMsgTypeEnum.SQL.name()));

                // c.解析：口径字段（字段数值）&处理策略
                String variableValue = item.getVariableValue();
                String orderStrategy = item.getOrderStrategy();
                if (StrUtil.isNotBlank(variableValue)) {
                    // 处理策略为“结算上月”
                    if(FundMonthlyStrategyEnum.A.name().equals(orderStrategy)){
                        Date addDate = DateUtils.addMonths(calculateDate, -1);
                        String yearMonth = DateUtils.parseDateToStr(DateUtils.YYYY_MM, addDate);
                        criteriaSQL.append(" '").append(yearMonth+"-").append(variableValue).append("'");
                    }else if (FundMonthlyStrategyEnum.B.name().equals(orderStrategy)) {
                        String yearMonth = DateUtils.parseDateToStr(DateUtils.YYYY_MM, calculateDate);
                        criteriaSQL.append(" '").append(yearMonth+"-").append(variableValue).append("'");
                    } else if(FundMonthlyStrategyEnum.C.name().equals(orderStrategy)){
                        Date addDate = DateUtils.addMonths(calculateDate, 1);
                        String yearMonth = DateUtils.parseDateToStr(DateUtils.YYYY_MM, addDate);
                        criteriaSQL.append(" '").append(yearMonth+"-").append(variableValue).append("'");
                    }else{
                        criteriaSQL.append(" '").append(variableValue).append("'");
                    }
                }
                // d.逻辑运算符
                if (StrUtil.isNotBlank(item.getLogicalOperator()) && !"0".equals(item.getLogicalOperator())) {
                    criteriaSQL.append(" ").append(recnExpenseService.transLogicalOperator(item.getLogicalOperator(), "SQL")).append(" ");
                }
                criteriaSQL.append(" ");
            }

        }
        log.debug("基本法查询首期保单表达式拼接SQL：[ " + criteriaSQL + " ]");
        return criteriaSQL.toString();
    }

    /**
     * 提交审核
     *
     * @param commIds
     */
    @Override
    public void examComm(Long[] commIds) {
        for (Long commId : commIds) {
            ImcComm imcComm = imcCommMapper.selectImcCommById(commId);
            if (!"C".equals(imcComm.getStatus())) {
                throw new BusinessException(commId + "状态错误，只有已计算状态才可以审核");
            } else {
                imcComm.setStatus("D");
                imcCommMapper.updateImcComm(imcComm);
            }
        }

    }

    /**
     * 审核通过
     *
     * @param examCommForm
     */
    @Override
    public void examPassComm(ExamCommForm examCommForm) {
        Long[] commIds = examCommForm.getCommIds();
        for (Long commId : commIds) {
            ImcComm imcComm = imcCommMapper.selectImcCommById(commId);
            if (!"D".equals(imcComm.getStatus())) {
                throw new BusinessException(commId + "状态错误，只有审核中状态才可以审核");
            } else {
                ImcCommDetails imcCommDetails1 = new ImcCommDetails();
                imcCommDetails1.setCommId(commId);
                List<ImcCommDetails> commDetailsList = imcCommDetailsMapper.selectImcCommDetailsList(imcCommDetails1);
                for (ImcCommDetails imcCommDetails : commDetailsList) {
                    String firstOrderRiskIds = imcCommDetails.getFirstOrderRiskIds();
                    String renewalOrderRiskIds = imcCommDetails.getRenewalOrderRiskIds();
                    if(!StringUtils.isNull(firstOrderRiskIds)){
                        String replace = firstOrderRiskIds.replace("[", "").replace("]", "").replace(" ", "");
                        String[] split = replace.split(",");
                        for (String s : split) {
                            Long orderRiskId = Long.parseLong(s);
                            ImcOrderRisk imcOrderRisk = new ImcOrderRisk();
                            imcOrderRisk.setId(orderRiskId);
                            imcOrderRisk.setPayDate(DateUtils.parseDate(imcComm.getSettleMonth()+"-01"));
                            imcOrderRiskMapper.updateOrderRiskPayMonth(imcOrderRisk);
                        }
                    }
                    if(!StringUtils.isNull(renewalOrderRiskIds)){
                        String replace = renewalOrderRiskIds.replace("[","").replace("]","").replace(" ","");
                        String[] split = replace.split(",");
                        for (String s : split) {
                            Long orderRiskId = Long.parseLong(s);
                            ImcOrderRisk imcOrderRisk = new ImcOrderRisk();
                            imcOrderRisk.setId(orderRiskId);
                            imcOrderRisk.setPayDate(DateUtils.parseDate(imcComm.getSettleMonth()+"-01"));
                            imcOrderRiskMapper.updateOrderRiskPayMonth(imcOrderRisk);
                        }
                    }
                }
                imcComm.setStatus("E");
                imcComm.setApproveComment(examCommForm.getRemarks());
                imcCommMapper.updateImcComm(imcComm);

            }

        }
    }

    /**
     * 反结审核
     *
     * @param examCommForm
     */
    @Override
    public void examCancelComm(ExamCommForm examCommForm) {
        Long[] commIds = examCommForm.getCommIds();
        for (Long commId : commIds) {
            ImcComm imcComm = imcCommMapper.selectImcCommById(commId);
            if (!"E".equals(imcComm.getStatus())) {
                throw new BusinessException(commId + "状态错误，只有审核通过状态才可以反结");
            }
            ImcCommDetails imcCommDetails = new ImcCommDetails();
            imcCommDetails.setCommId(commId);
            List<ImcCommDetails> commDetailsList = imcCommDetailsMapper.selectImcCommDetailsList(imcCommDetails);
            for (ImcCommDetails imcCommDetail : commDetailsList) {
                String firstOrderRiskIds = imcCommDetail.getFirstOrderRiskIds();
                String renewalOrderRiskIds = imcCommDetail.getRenewalOrderRiskIds();
                if(!StringUtils.isNull(firstOrderRiskIds)){
                    String replace = firstOrderRiskIds.replace("[", "").replace("]", "").replace(" ", "");
                    String[] split = replace.split(",");
                    for (String s : split) {
                        Long orderRiskId = Long.parseLong(s);
                        ImcOrderRisk imcOrderRisk = new ImcOrderRisk();
                        imcOrderRisk.setId(orderRiskId);
                        imcOrderRisk.setPayDate(null);
                        imcOrderRiskMapper.updateOrderRiskPayMonth(imcOrderRisk);
                    }
                }
                if(!StringUtils.isNull(renewalOrderRiskIds)){
                    String replace = renewalOrderRiskIds.replace("[","").replace("]","").replace(" ","");
                    String[] split = replace.split(",");
                    for (String s : split) {
                        Long orderRiskId = Long.parseLong(s);
                        ImcOrderRisk imcOrderRisk = new ImcOrderRisk();
                        imcOrderRisk.setId(orderRiskId);
                        imcOrderRisk.setPayDate(null);
                        imcOrderRiskMapper.updateOrderRiskPayMonth(imcOrderRisk);
                    }
                }
            }
            imcComm.setStatus("D");
            imcComm.setRevertComment(examCommForm.getRemarks());
            imcCommMapper.updateImcComm(imcComm);
        }
    }

    /**
     * 退回审核
     *
     * @param examCommForm
     */
    @Override
    public void returnComm(ExamCommForm examCommForm) {
        //commdetails做逻辑删除   C D 状态改为A
        Long[] commIds = examCommForm.getCommIds();
        for (Long commId : commIds) {
            ImcComm imcComm = imcCommMapper.selectImcCommById(commId);
            if (!"C".equals(imcComm.getStatus()) && !"D".equals(imcComm.getStatus())) {
                throw new BusinessException(commId + "状态错误，只有已计算或审核中状态才可以退回");
            }
            ImcCommDetails imcCommDetails = new ImcCommDetails();
            imcCommDetails.setCommId(commId);
            List<ImcCommDetails> commDetailsList = imcCommDetailsMapper.selectImcCommDetailsList(imcCommDetails);
            for (ImcCommDetails imcCommDetail : commDetailsList) {
                imcCommDetail.setIsDeleted(imcCommDetail.getId().toString());
                imcCommDetailsMapper.updateImcCommDetails(imcCommDetail);
            }
            imcComm.setStatus("A");
            imcComm.setReturnComment(examCommForm.getRemarks());
            imcCommMapper.updateImcComm(imcComm);
        }
    }

    /**
     * 代理人佣金计算
     * @param commId
     * @param orgId
     * @return
     */
    @Transactional
    @Override
    public ImcComm calculateDetail(Long commId, Long orgId) {
        //删除旧数据
        imcCommDetailsMapper.deleteByCommId(commId);
        //再计算新数据
        ImcComm imcComm = imcCommMapper.selectImcCommById(commId);
        imcComm.setStatus("B");
        imcCommMapper.updateImcComm(imcComm);//计算中
        return imcComm;
    }

    /**
     * 代理人数据保存到imcCommDetails中
     * @param imcComm
     * @return
     */
    @Transactional
    @Override
    public List<Long> asnyCalculateDetail(ImcComm imcComm) {
        Long commId = imcComm.getId();
        String settleMonth = imcComm.getSettleMonth();
        Long tenantId = SecurityUtils.getTenantId();
        //保单维度代理人id
        ImcCommRisk imcCommRisk = new ImcCommRisk();
        imcCommRisk.setCommId(commId);
        imcCommRisk.setIsDeleted(IsDeletedEnum.N.getCode());
        imcCommRisk.setTenantId(tenantId);
        List<ImcCommRisk> imcCommRisks = imcCommRiskMapper.selectImcCommRiskList(imcCommRisk);
        List<Long> brokerIdList = imcCommRisks.stream().map(ImcCommRisk::getBrokerId).collect(Collectors.toList());

        //查询基本法相关信息 获得基本法结算口径
        String criteriaSQL = getBrokerCriteriaSQL(settleMonth+"-01",imcComm.getFundId());

        List<BrokerVo> brokerVos = imcBrokerMapper.getBrokerVoByCriteria(criteriaSQL,tenantId);
        List<Long> brokerVoIdList = brokerVos.stream().map(BrokerVo::getId).collect(Collectors.toList());
        List<Long> brokerIds = Stream.of(brokerIdList, brokerVoIdList).flatMap(Collection::stream).distinct().collect(Collectors.toList());

        List<BrokerVo> brokerVoToCommDetail = imcBrokerMapper.selectBrokerInfoToCommDetail(brokerIds);

        ArrayList<ImcCommDetails> imcCommDetails1 = new ArrayList<>();
        //保单数据保存到imc_comm_detail中 每个代理人一条数据
        for (BrokerVo brokerVo : brokerVoToCommDetail) {
            CommDetailsVo commDetailsVo = imcBrokerMapper.selectCommDetailsBroker(brokerVo.getId());
            ImcCommDetails imcCommDetails = new ImcCommDetails();
            imcCommDetails.setCommId(commId);
            imcCommDetails.setBrokerId(brokerVo.getId());
            imcCommDetails.setOrgId(brokerVo.getOrgId());
            imcCommDetails.setTeamRootId(brokerVo.getRootTeamId());
            imcCommDetails.setTeamId(brokerVo.getTeamId());
            imcCommDetails.setRecommenderId(commDetailsVo.getRecommenderId());
            imcCommDetails.setIndirectRecommenderId(commDetailsVo.getIndirectRecommenderId());
            //联合comm_risk获得首年标保 保费佣金等信息
            CommDetailsVo commDetailsVoPrem = imcCommRiskMapper.selectCommDetailsPremFirst(brokerVo.getId(), commId);
            if (commDetailsVoPrem != null) {
                imcCommDetails.setFirstPrem(commDetailsVoPrem.getFirstPrem());
                imcCommDetails.setStandPrem(commDetailsVoPrem.getStandPrem());
                imcCommDetails.setFirstComm(commDetailsVoPrem.getFirstComm());
                imcCommDetails.setFirstOrderRiskIds(commDetailsVoPrem.getFirstOrderRiskIds());
            }
            //续期查询
            System.out.println(brokerVo.getId()+"==="+commId);
            CommDetailsVo commDetailsVoRenw = imcCommRiskMapper.selectCommDetailsPremRenw(brokerVo.getId(),commId);
            if (commDetailsVoRenw != null) {
                imcCommDetails.setRenewalOrderRiskIds(commDetailsVoRenw.getRenewalOrderRiskIds());
                imcCommDetails.setRenewalPrem(commDetailsVoRenw.getRenewalPrem());
                imcCommDetails.setRenewalComm(commDetailsVoRenw.getRenewalComm());
            }
            imcCommDetails.setCreateId(SecurityUtils.getUsername());
            imcCommDetails.setCreateTime(DateUtils.getNowDate());
            imcCommDetails.setUpdateId(SecurityUtils.getUsername());
            imcCommDetails.setUpdateTime(DateUtils.getNowDate());
            imcCommDetails.setTenantId(tenantId);
            imcCommDetails.setIsDeleted(IsDeletedEnum.N.getCode());
            imcCommDetails1.add(imcCommDetails);
        }

        imcCommDetailsMapper.insertImcCommDetailsList(imcCommDetails1);
        return brokerIds;
    }

    /**
     * 调用基本法计算
     * @param commId
     * @param brokerIds
     * @param settleMonth
     */
    @Async
    @Override
    public void calculateBasic(Long commId, List<Long> brokerIds, String settleMonth) {
        ImcComm imcComm = imcCommMapper.selectImcCommById(commId);
        try{
            ImcFund imcFund = imcFundMapper.selectImcFundById(imcComm.getFundId());
            List<BasicFACT> factList = basicService.createFactList(commId, brokerIds, settleMonth);
            Map<Long,BasicFACT> brokerFactMap = factList.stream().collect(Collectors.toMap(b->b.getBrokerInfo().getBrokerInfoBase().getBrokerId(), b->b));
            //代理人基本法
            for (BasicFACT fact : factList) {
                //查询数据库获得url地址
                basicService.calculateCommission(brokerFactMap, fact, imcFund.getDrlUrl());
            }
            //调用基本法结束后变成已计算
            imcComm.setStatus("C");
            imcComm.setRemark(null);
            imcCommMapper.updateImcComm(imcComm);
        } catch (Exception e) {
            //修改主表信息
            imcComm.setStatus("A");
            imcComm.setRemark(e.getMessage());
            imcCommMapper.updateImcComm(imcComm);
            //删除佣金明细
            imcCommDetailsMapper.deleteByCommId(commId);
            log.error(e.getMessage());
            throw new BusinessException("计算发生错误，请检查:"+e.getMessage());
        }
    }


    private String getBrokerCriteriaSQL(String settleMonth, Long fundId) {
        StringBuilder criteriaSQL = new StringBuilder();
        List<ImcFundBrokerExpression> fundBrokerExpressions = this.fundBrokerExpressionMapper.listfundBrokerExpressionByFundId(fundId,SecurityUtils.getTenantId());
        if (CollUtil.isNotEmpty(fundBrokerExpressions)) {
            for (ImcFundBrokerExpression item : fundBrokerExpressions) {
                // a.解析：口径字段（字段名称）：如果不为括号则转换为 r.字段名
                ImcFundBrokerVariable fundBrokerVariable = this.fundBrokerVariableMapper.selectImcFundBrokerVariableById(item.getBrokerVariableId());
                if ("left_bracket".equals(fundBrokerVariable.getVariableName()) || "right_bracket".equals(fundBrokerVariable.getVariableName())) {
                    criteriaSQL.append(fundBrokerVariable.getVariableLabel());
                } else {
                    criteriaSQL.append("broker.").append(fundBrokerVariable.getVariableName());
                }

                // b.解析：运算符
                criteriaSQL.append(" ").append(recnExpenseService.transOperator(item.getOperator(), ExpenseExpressionMsgTypeEnum.SQL.name()));

                // c.解析：口径字段（字段数值）&处理策略
                String variableValue = item.getVariableValue();
                String brokerStrategy = item.getBrokerStrategy();
                if (StrUtil.isNotBlank(variableValue)) {
                    // 处理策略为“结算上月”
                    if(FundMonthlyStrategyEnum.A.name().equals(brokerStrategy)){
                        Date addDate = DateUtils.addMonths(DateUtils.parseDate(settleMonth), -1);
                        String yearMonth = DateUtils.parseDateToStr(DateUtils.YYYY_MM, addDate);
                        criteriaSQL.append(" '").append(yearMonth+"-").append(variableValue).append("'");
                    }else if (FundMonthlyStrategyEnum.B.name().equals(brokerStrategy)) {
                        String yearMonth = settleMonth;
                        criteriaSQL.append(" '").append(yearMonth+"-").append(variableValue).append("'");
                    } else if(FundMonthlyStrategyEnum.C.name().equals(brokerStrategy)){
                        Date addDate = DateUtils.addMonths(DateUtils.parseDate(settleMonth), 1);
                        String yearMonth = DateUtils.parseDateToStr(DateUtils.YYYY_MM, addDate);
                        criteriaSQL.append(" '").append(yearMonth+"-").append(variableValue).append("'");
                    }else{
                        criteriaSQL.append(" '").append(variableValue).append("'");
                    }
                }
                // d.逻辑运算符
                if (StrUtil.isNotBlank(item.getLogicalOperator()) && !"0".equals(item.getLogicalOperator())) {
                    criteriaSQL.append(" ").append(recnExpenseService.transLogicalOperator(item.getLogicalOperator(), "SQL")).append(" ");
                }
                criteriaSQL.append(" ");
            }
        }
        log.debug("基本法查询代理人表达式拼接SQL：[ " + criteriaSQL + " ]");
        return criteriaSQL.toString();
    }
}
